import Dep from './Dep'
import observe from './observe'

export default function defineReactive(data, key, val) {
  // 由于需要在get和set中使用dep,所以这里也要new一个dep的实例
  const dep = new Dep()
  // console.log('defineReactive', data, key)
  if (arguments.length == 2) {
    val = data[key]
  }

  // 子元素要进行observe,至此形成递归.这个递归不是函数自己调用自己,而是多个函数,类的循环调用
  let childOb = observe(val)

  Object.defineProperty(data, key, {
    // value和get不能同时存在
    // value: 3,
    // 是否可写(不能和get同时存在)
    // writable: true,
    // 是否可以被枚举
    // enumerable: true
    // 劫持了a属性,用户访问a属性时就会触发get

    // 可枚举
    enumerable: true,
    // 可以被配置,比如可以被delete
    configurable: true,
    get() {
      // 如果现在处于依赖的收集阶段
      if (Dep.target) {
        // 把当前的watcher添加到dep数组中
        // console.log(1213213)
        dep.depend()
        // 如果有子元素,还要让子元素添加依赖
        if (childOb) {
          childOb.dep.depend()
        }
      }
      return val
    },
    set(newValue) {
      if (val === newValue) {
        return
      }
      val = newValue
      childOb = observe(newValue)
      // 修改数据是触发notify
      dep.notify()
    }
  })
}
